package chapter10.section5;
//程序10-8：随机文件访问实例

import java.io.EOFException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;

public class RandomAccessFileDemo {
    public static void dataOut(String fn, List<Account> as) throws IOException {
        RandomAccessFile raf = new RandomAccessFile(fn, "rw");
        for (Account a : as) {
            raf.writeBytes(a.getId());
            byte[] names = a.getName().getBytes();// 将姓名转换为字节
            // 将一个包含10个空格的字符串转换为字节数组用于固定姓名的宽度
            byte[] fixName = "          ".getBytes();
            System.arraycopy(names, 0, fixName, 0, names.length);
            raf.write(fixName);//固定输出10个字节的姓名
            raf.writeInt(a.getBalance());//输出整数的4个字节
            raf.writeBytes("\r\n");//输出两个字节的换行和回车
        }
        raf.close();
    }

    //根据制定的账户id，在文件中查询，返回查到的对象，否则返回null
    public static Account findById(String fn, String aid) throws IOException {
        RandomAccessFile raf = new RandomAccessFile(fn, "rw");
        Account a = null;
        while (true) {
            // 读取账户id固定的10个字节，并转换为字符串
            byte[] bid = new byte[10];
            int len = raf.read(bid);
            if (len == -1) {// 如果返回-1表示文件结束了
                break;
            }
            String id = new String(bid);//恢复成字符串
            if (id.equals(aid)) {// 如果找到了，则顺势读取后续的姓名和余额
                byte[] bname = new byte[10];
                len = raf.read(bname);
                if (len == -1) {// 如果返回-1表示文件结束了
                    break;
                }
                String name = new String(bname);
                int balance = 0;
                try {
                    balance = raf.readInt();
                } catch (EOFException e) {
                    break;// 此异常表示文件结束
                }
                a = new Account(id, name.trim(), balance);
            } else {//如果没有找到，跳过此行剩余的字节，开始下一轮的查找
                // 隔过的16字节包括10个字节的姓名和4个字节的整数以及2个字节换行回车
                len = raf.skipBytes(16);
                if (len < 16) break;// 如果不足16个字节，表示文件结束
            }
        }
        return a;
    }

    public static void main(String[] args) throws IOException {
        List<Account> as = new ArrayList<Account>();
        as.add(new Account("1600394098", "张伟", 2000));
        as.add(new Account("1600394099", "王国美", 3000));
        as.add(new Account("1600394118", "丁理惠", 2300));
        as.add(new Account("1600394120", "贺嘉怡", 12000));
        dataOut("account2.dat", as);
        Account a = findById("account2.dat", "1600394120");
        System.out.println(a);
    }
}
